package cell

import (
	"github.com/treelab/updatecolumn/models"
)

// InstanceType of cell
func InstanceType() int32 {
	return models.Datetime
}

  //#region cell value convert
  cellValueToString({ cell, column }: { cell: Cell; column: Column }) {
    return getFormattedDateTime(cell.dateTime || '', {
      dateFormat: column.dateFormat as DateFormat,
      timeFormat: column.timeFormat as TimeFormat,
      includeTime: column.includeTime,
    }).trim();
  }
  cellValueToDatetime({ column, cell }: IColumnAndCell) {
    return cell?.dateTime || '';
  }

  cellValueToNumber({ column, cell }: IColumnAndCell) {
    const dateOptions = {
      dateFormat: column!.dateFormat as DateFormat,
      timeFormat: column!.timeFormat as TimeFormat,
      includeTime: column!.includeTime,
    };
    const result = parseFloat(getFormattedDateTime(cell.dateTime || '', dateOptions).replace(/[^0-9.-]/g, ''));
    return isNaN(result) ? 0 : result;
  }

  cellValueToSelect({ cell, column }: IColumnAndCell) {
    const dateOptions = {
      dateFormat: column.dateFormat as DateFormat,
      timeFormat: column.timeFormat as TimeFormat,
      includeTime: column.includeTime,
    };
    const time = getFormattedDateTime(cell.dateTime || '', dateOptions);
    const option = _.find(column.hasColumnOption.get(), i => _.trim(i.name) === _.trim(time));
    return option;
  }

  cellValueToMultiSelect({ cell, column }: IColumnAndCell) {
    const dateOptions = {
      dateFormat: column.dateFormat as DateFormat,
      timeFormat: column.timeFormat as TimeFormat,
      includeTime: column.includeTime,
    };
    const time = getFormattedDateTime(cell.dateTime || '', dateOptions);
    const options = _.filter(column.hasColumnOption.get(), i => _.trim(i.name) === _.trim(time));
    return options;
  }
  //#endregion

  setCellValue({ cell, action }: { cell: Cell; action: UpdateCellAction }) {
    const time = (action.value as DateTimeCellValue).dateTime;
    const toDate = moment(time);
    cell.dateTime = toDate.isValid() ? toDate.format() : '';
    return this;
  }

  getCellValue(cell: Cell) {
    return cell.dateTime;
  }

  convertCell(
    command: UpdateColumn_v2,
    o: CommonOptions,
    { columnCopy, rows, referenceColumns }: { columnCopy: Column; rows: Row[]; referenceColumns?: Column[] },
  ) {
    const { column, columnConfig } = command;
    const { type: toType } = columnConfig;
    const { columnType: fromType } = columnCopy;

    const cells = column.hasCell.get();
    const events = new EventHelper();
    const fromCellHandle = this.instanceFactory.getCellInstance(fromType as ColumnType);
    if (this.needEmptyCell(command)) {
      fromCellHandle.emptyCells(command, cells, false, o);
    }
    if (cells.length) {
      const visableNameMapping = new Map<string, string>();
      _.forEach(cells, cell => {
        const action = {
          type: UpdateAction.SET_VALUE,
          value: { ...command.columnConfig, type: toType },
        };
        const updateCell = {
          ...command,
          action,
          _metadata: { ...command._metadata, source: Source.SAGA },
        };
        const value = action.value as DateTimeCellValue;
        value.dateTime = fromCellHandle.cellValueToDatetime({ column, cell });
        const rowData = super.upsertCell(cell, { command: updateCell }, { ...o, events }, { columnCopy });
        if (rowData) {
          visableNameMapping.set(rowData.uid, rowData.visibleName);
        }
      });
      this.updateReferenceColumnAndDependencies({
        column,
        visableNameMapping,
        o,
        _metadata: command._metadata,
        referenceColumns,
      });
    }

    o.events.bulkAddEvents(...events);
    return this;
  }

  emptyCells(command: UpdateColumn_v2, cells: readonly Cell[], deleteCells: boolean, o: CommonOptions) {
    if (!deleteCells) {
      _.forEach(cells, cell => {
        o.delQuads.push(...this.dgraphHelperService.getRemoveObjectQuads(cell.uid!, 'dateTime'));
      });
    }
    super.emptyCells(command, cells, deleteCells, o);
    return this;
  }

